package kz.pompei.porelinar.impls;

import static kz.pompei.porelinar.ifaces.ErrorCode.BACKSLASH_BEFORE_KAV;
import static kz.pompei.porelinar.ifaces.ErrorCode.UNCOMPLETE_KAV;
import kz.pompei.porelinar.ifaces.TopAtomAcceptor;
import kz.pompei.porelinar.ifaces.TopAtomAnalizer;

public class TopAtomAnalizerImpl implements TopAtomAnalizer {
  private TopAtomAcceptor acceptor;
  
  @Override
  public void setTopAtomAcceptor(TopAtomAcceptor topAtomAcceptor) {
    acceptor = topAtomAcceptor;
  }
  
  @Override
  public void acceptChars(char[] chars) {
    
    acceptor.start(chars);
    
    char kavChar = 0;
    
    int curLine = 0, curCol = 0;
    
    int beginPos = 0;
    int beginLine = 0, beginCol = 0;
    int prevLine = 0, prevCol = 0;
    
    char prevC = 0;
    
    C1: for (int i = 0; i < chars.length; i++) {
      char c = chars[i];
      if (c == '\r') continue C1;
      
      C2: {
        if (kavChar == 0) {
          if (c == '"' || c == '\'') {
            if (prevC == '\\') {
              acceptor.error(BACKSLASH_BEFORE_KAV, i - 1, 2, prevLine, prevCol);
            }
            
            if (i > beginPos) {
              acceptor.accept(beginPos, i - beginPos, beginLine, beginCol);
            }
            
            beginPos = i;
            beginLine = curLine;
            beginCol = curCol;
            
            kavChar = c;
            
            break C2;
          }
          
          if (c == '\n') {
            if (i > beginPos) {
              acceptor.accept(beginPos, i - beginPos, beginLine, beginCol);
            }
            
            beginPos = i + 1;
            beginLine = curLine;
            beginCol = 0;
            
            acceptor.newLine(curLine);
            break C2;
          }
          
          break C2;
        }
        
        //in kav...
        
        if (kavChar == c) {
          if (prevC == '\\') break C2;
          
          acceptor.accept(beginPos, i - beginPos + 1, beginLine, beginCol);
          
          kavChar = 0;
          beginPos = i + 1;
          beginLine = curLine;
          beginCol = curCol + 1;
          
          break C2;
        }
        
      }
      
      prevC = c;
      
      prevLine = curLine;
      prevCol = curCol;
      if (c == '\n') {
        curLine++;
        curCol = 0;
      } else {
        curCol++;
      }
    }
    
    if (chars.length > beginPos) {
      acceptor.accept(beginPos, chars.length - beginPos, beginLine, beginCol);
    }
    
    if (kavChar != 0) {
      acceptor.error(UNCOMPLETE_KAV, chars.length, 0, curLine, curCol);
    }
    
    acceptor.finish();
  }
}
